package permission

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/fx"
	"go-admin/base/dao"
	"go-admin/base/utils"

	"go-admin/base/internal/svc"
	"go-admin/base/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type ListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListLogic {
	return &ListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ListLogic) List(req *types.PermissionQueryReqDTO) (resp *types.PermissionRespDTOS, err error) {
	permissions, err := l.svcCtx.PermissionModel.FindAll(l.ctx)
	if err != nil {
		_ = fmt.Errorf(err.Error())
		return nil, err
	}
	menuPermissions := utils.Collector[*dao.Permission](fx.From(func(source chan<- any) {
		for _, permission := range permissions {
			source <- permission
		}
	}).Filter(func(item any) bool {
		permission := item.(*dao.Permission)
		return permission.Type.String == "MENU"
	}))
	var permissionRespDTOs []types.PermissionRespDTO
	for _, menuPermission := range menuPermissions {
		permissionId := menuPermission.Id
		var permissionRespDTOChild []types.PermissionRespDTO
		fx.From(func(source chan<- any) {
			for _, permission := range permissions {
				source <- permission
			}
		}).Filter(func(item any) bool {
			permission := item.(*dao.Permission)
			return permission.Type.String == "BUTTON" && permission.ParentId.Int64 == permissionId
		}).ForEach(func(item any) {
			permission := item.(*dao.Permission)
			permissionRespDTOChild = append(permissionRespDTOChild, types.PermissionRespDTO{
				PermissionID: permission.Id,
				ParentID:     permission.ParentId.Int64,
				URL:          permission.Url.String,
				Type:         permission.Type.String,
				Name:         permission.Name.String,
				Number:       permission.Number.String,
			})
		})

		permissionRespDTOs = append(permissionRespDTOs, types.PermissionRespDTO{
			Children:     permissionRespDTOChild,
			PermissionID: menuPermission.Id,
			URL:          menuPermission.Url.String,
			Type:         menuPermission.Type.String,
			Name:         menuPermission.Name.String,
			Number:       menuPermission.Number.String,
		})
	}

	return &types.PermissionRespDTOS{
		Data: permissionRespDTOs,
		Result: types.Result{
			Code: 200,
		},
	}, nil
}
